// Kruskal算法模版（洛谷）
// 静态空间实现
// 测试链接 : https://www.luogu.com.cn/problem/P3366
// 提交以下所有代码，可以直接通过

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// 时间复杂度O(m * log m) + O(n + m)

const int MAXN = 5001;
const int MAXM = 200001;

// 并查集
int father[MAXN];

// u, v, w
vector<vector<int>> edges(MAXM, vector<int>(3));
int n, m;

// 并查集初始化
void Build()
{
    for(int i = 1; i <= n; ++i)
    {
        father[i] = i;
    }
}

// 找出 i 节点的父亲，在此过程中同时做路径压缩
int Find(int i)
{
    // if(i != father[i])
    // {
    //     father[i] = Find(father[i]);
    // }
    // return father[i];
    return i == father[i] ? i : father[i] = Find(father[i]);
}

// 如果 x 和 y 本来就是一个集合，返回 false
// 如果 x 和 y 不是一个集合，合并之后返回 true
bool Union(int x, int y)
{
    int fx = Find(x);
    int fy = Find(y);
    if(fx != fy)
    {
        father[fx] = fy;
        return true;
    }
    return false;
}

int main()
{
    cin >> n >> m;
    Build();
    for(int i = 0; i < m; ++i)
    {
        cin >> edges[i][0] >> edges[i][1] >> edges[i][2];
    }

    sort(edges.begin(), edges.begin() + m, [&](vector<int>& a, vector<int>& b){
        return a[2] < b[2];
    });
    int ans = 0, edgeCnt = 0;
    for(int i = 0; i < m; ++i)
    {
        auto& edge = edges[i];
        if(Union(edge[0], edge[1]))
        {
            ++edgeCnt;
            ans += edge[2];
        }
    }
    
    if(edgeCnt == n - 1)
        cout << ans << endl;
    else
        cout << "orz" << endl;

    return 0;
}